package edu.gatech.cs2340.mule.presenter;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

import edu.gatech.cs2340.mule.model.GameConfigModel;
import edu.gatech.cs2340.mule.model.MuleGame;
import edu.gatech.cs2340.mule.view.CharacterSetUpFrame;
import edu.gatech.cs2340.mule.view.GameSetUpFrame;
import edu.gatech.cs2340.mule.view.TitleScreenPanel;

/**
 * 
 * Takes care of presenting the GUI for the Game configuration
 * and transferring the data to the GameConfigModel
 * 
 * @author Zach Elliott
 *
 */
public class GameConfigPresenter implements Serializable {

	private static final long serialVersionUID = 8707360778624818158L;
	
	private static final String LOAD_GAME_NAME = "mule.dat";	
	
	private GameSetUpFrame gameSetupView;
	private CharacterSetUpFrame characterSetupView;
	private TitleScreenPanel titleScreenView;
	private GameConfigModel model;
	
	/**
	 * Creates a Presenter for configuration given a model and view
	 * 
	 * @param v the GUI that will be tied to the presenter
	 * @param m the model that will store data from the view
	 */
	public GameConfigPresenter(TitleScreenPanel v, GameConfigModel m) {
		titleScreenView = v;
		model = m;
		gameSetupView = new GameSetUpFrame();
		gameSetupView.setVisible(false);
		
		titleScreenView.addNewListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				titleScreenView.setVisible(false);
				gameSetupView.setVisible(true);
			}
		});
		
		gameSetupView.registerOK(new ActionListener() {
			//when first screen's OK button is pressed...
            @Override
            public void actionPerformed(ActionEvent ae) {
            	setPlayerCount();
            	setDifficulty();
            	setMapType();
            	
            	CharacterSetUpFrame charFrame = new CharacterSetUpFrame();
            	gameSetupView.setVisible(false);
            	characterSetupView = charFrame;
            	characterSetupView.registerOK(new ActionListener() {
        			//when second screen's OK button is pressed...
                    @Override
                    public void actionPerformed(ActionEvent ae) {
                    	if(!model.setPlayerInfo(characterSetupView.getColor(), characterSetupView.getName(), characterSetupView.getRace())) {
                    		characterSetupView.setVisible(false);
                    		launchGame();
                    	}
                    	else {
                    		characterSetupView.removePickedColor(characterSetupView.getPickedColorIndex());
                    		characterSetupView.clearEntries();
                    	}
                    } 
                }); 
            }
        });
		
		addLoadListener();
	}
	
	/**
	 * Adds a listener to the load game buttnon
	 * 
	 */
	private void addLoadListener() {
		titleScreenView.addLoadListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				loadGame();
			}
		});
	}
	
	/**
	 *  Retrieves the player count set in the view's spinner and stores
	 *  it in the model.
	 */
	private void setPlayerCount() {
		model.setPlayerCount(gameSetupView.getPlayerCount());
	}
	
	/**
	 *  Retrieves the difficulty set in the view's drop down box and stores
	 *  it in the model.
	 */
	private void setDifficulty() {
		model.setDifficulty(gameSetupView.getDifficulty());
	}
	
	/**
	 *  Retrieves the map type set in the view's drop down box and stores
	 *  it in the model.
	 */
	private void setMapType() {
		model.setMapType(gameSetupView.getMapType());
	}
	
	/**
	 * Loads the saved game from file
	 * 
	 */
	private void loadGame() {
		MuleGamePresenter p = null;
		try {
			ObjectInputStream in = new ObjectInputStream(new FileInputStream(LOAD_GAME_NAME));
			p = (MuleGamePresenter) in.readObject();
			p.restoreGame();
			gameSetupView.setVisible(false);
		}
		catch (FileNotFoundException e) {
			System.out.println("File not found");
		}
		catch (IOException e) {
			System.out.println("General IO Error");
		}
		catch (ClassNotFoundException e) {
			System.out.println("Class not found on loading");
		}
	}
	
	/**
	 * Once the OK button is clicked on the view, launch the game based on
	 * the settings selected.
	 */
	private void launchGame() {
		MuleGame game = new MuleGame(model.getPlayers(), model.getMapType(),
				model.getDifficulty());
		
		//transfer control of the GUI to a main presenter
		MuleGamePresenter presenter = new MuleGamePresenter(game);
	}
}
